package com.example.scan.util;

import com.example.scan.constant.DateTimeFormatter;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.util.ReflectionUtils;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.math.BigDecimal;
import java.text.ParseException;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;
import java.util.Map;

/**
 * 反射工具类
 */
public class ReflectionUtil {
    /**
     * 将下划线字段map 映射到实体
     *
     * @param c
     * @param map
     * @return
     * @throws NoSuchMethodException
     * @throws IllegalAccessException
     * @throws InvocationTargetException
     * @throws InstantiationException
     */
    public static Object mapToHump(Class c, Map<String, Object> map) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        Constructor constructor = ReflectionUtils.accessibleConstructor(c);
        Object object = constructor.newInstance();
        map.forEach((o, o2) -> {
            if (o2 instanceof Object[]) {
                o2 = ((Object[]) o2)[0];
            }
            Field field = ReflectionUtils.findField(c, StringUtil.underlineToCamel(o));
            if (field != null) {
                field.setAccessible(true);
                if (field.getType() == Date.class) {
                    try {
                        field.set(object, DateUtils.parseDate(o2.toString(), DateTimeFormatter.DATE_TIME_STRING_FORMATTER, DateTimeFormatter.DATE_STRING_FORMATTER));
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    } catch (ParseException e) {
                        e.printStackTrace();
                    }

                } else if (field.getType() == LocalDateTime.class) {
                    try {
                        ReflectionUtils.setField(field, object, DateUtils.parseDate(o2.toString(), DateTimeFormatter.DATE_TIME_STRING_FORMATTER, DateTimeFormatter.DATE_STRING_FORMATTER).toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime());
                    } catch (ParseException e) {
                        e.printStackTrace();
                    }

                } else if (field.getType() == BigDecimal.class) {
                    ReflectionUtils.setField(field, object, BigDecimal.valueOf(Double.valueOf(o2.toString())));

                } else if (field.getType() == Double.class) {
                    ReflectionUtils.setField(field, object, Double.valueOf(o2.toString()));

                } else if (field.getType() == Long.class) {
                    ReflectionUtils.setField(field, object, Long.valueOf(o2.toString()));

                }
                else if (field.getType() == Integer.class) {
                    ReflectionUtils.setField(field, object, Integer.valueOf(o2.toString()));

                }
                else if (field.getType().isEnum()) {
                    Class enumClass = field.getType();
                    Enum anEnum = Enum.valueOf(enumClass, (String) o2);
                    ReflectionUtils.setField(field, object, anEnum);
                } else {
                    ReflectionUtils.setField(field, object, o2);
                }
            }
        });
        return object;
    }

 /*   public static void main(String[] args) throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
        Map map = new Hashtable();
        map.put("trade_status", "WAIT_BUYER_PAY");
        map.put("receipt_amount", "0.01");
        map.put("gmt_create", "2019-02-02 12:12:30");
        map.put("app_id", "app_id");
        Object o = mapToHump(Object.class, map);
        System.out.printf("");
    }*/
}
